import java.util.ArrayList;

public class Simulator 
{
	public static void simulate(final ArrayList<Task> tasks, final ArrayList<Job> initJobs, 
			int numberOfTimeUnits) throws Exception 
	{
		// copy the job list that it could be modified (jobs removed)
		ArrayList<Job> jobs = new ArrayList<Job>();
		for(Job job : initJobs)
		{
			jobs.add(job);
		}

		//Simulate
		for(int i = 0; i < numberOfTimeUnits; i++) 
		{
			Job currentJob = null;
			for(Job job : jobs)
			{
				//serve job that is released and has the highest priority
				if(job.getRelease() <= i && (currentJob == null || compareJobs(job, currentJob))) 
				{
					currentJob = job;
				}
			}
			
			if(currentJob != null)
			{
				currentJob.getExecTime().add(i);

				if(currentJob.getStart() == -1)
				{
					currentJob.setStart(i);
				}
				if(currentJob.getTime() != 0)
				{
					currentJob.setTime(currentJob.getTime() - 1);
				}

				//Job is finish being served
				if(currentJob.getTime() == 0) 
				{	
					currentJob.setResponse(i - currentJob.getRelease());

					if(currentJob.getOwner().getWcrt() < currentJob.getResponse()) 
					{
						currentJob.getOwner().setWcrt(currentJob.getResponse());
					}

					jobs.remove(currentJob);
				}
			}
		}
	}

	// if j1 has a higher priority than j2 (priority "1" is higher than "2")
	// if priorities for some reason are equal then task ids are compared
	private static boolean compareJobs(Job j1, Job j2)
	{
		
		if(j1.getOwner().getPriority() < j2.getOwner().getPriority())
		{
			return true;
		}
		
		// the owner is the same. j1 missed its deadline
		if(j1.getOwner().equals(j2.getOwner()))
		{
			return false;
		}

		if(j1.getOwner().getPriority() == j2.getOwner().getPriority())
		{
			if(j1.getOwner().getId() < j2.getOwner().getId())
			{
				return true;
			}
			if(j1.getOwner().getId() == j2.getOwner().getId())
			{
				throw new RuntimeException("Two tasks have the same name and id! Are they the same one task?..");
			}
		}

		return false;
	}
}
